<?php

namespace app\api\controller;

use app\common\traits\ApiTrait;
use support\Request;
use support\Response;
use think\facade\Db;
use Tinywan\Jwt\JwtToken;
use Yansongda\Pay\Pay;

class ActivityController
{
    use ApiTrait;

    protected $noNeedLogin = ['wxappQrcode'];

    /**
     * 获取活动信息
     * @param Request $request
     * @return void
     */
    public function getInfo(Request $request) : Response
    {
        if (!request()->isGet()) {
            return $this->reError('请求方式错误');
        }

        $activityId = $request->get('activityId');
        $recomUserId = $request->get('recomUserId');

        $jwt = JwtToken::getExtend();
        $user = Db::name('user')->where(['id' => $jwt['id']])->find();
        $data = Db::name('activity')->where(['id' => $activityId])->find();
        if (!empty($data)) {
            // 增加浏览量
            Db::name('activity')->where(['id' => $activityId])->setInc('visitor_num');
            // 查询该参与人员数据是否存在
            $visitor = Db::name('activity_visitor')->where(['activity_id' => $activityId, 'user_id' => $user['id']])->count();
            if (empty($visitor)) {
                // 增加操作日志
                $name = Db::name('order')->where(['id' => $activityId, 'user_id' => $user['id']])->value('name') ?? Db::name('user')->where(['id' => $recomUserId])->value('nickname');
                Db::name('activity_operation_log')->insert([
                    'activity_id' => $activityId,
                    'user_id' => $user['id'],
                    'type' => 1,
                    'record' => '通过'.$name.'邀请访问活动',
                    'create_time' => date('Y-m-d H:i:s'),
                ]);
                // 增加参与人数
                Db::name('activity')->where(['id' => $activityId])->setInc('join_num');
                // 增加参与人员数据
                $visitorId = Db::name('activity_visitor')->insertGetId([
                    'activity_id' => $activityId,
                    'recom_user_id' => empty($recomUserId) ? 0 : $recomUserId,
                    'user_id' => $user['id'],
                    'activity_draw_num' => Db::name('activity')->where(['id' => $activityId])->value('draw_prize_number'),
                ]);
                // 查询溯源员工
                $recomUserRole = Db::name('activity_user_role')->where(['user_id' => $recomUserId, 'activity_id' => $activityId])->value('role');
                if (!empty($recomUserRole) && $recomUserRole == 2) {
                    $clerkUserId = $recomUserId;
                } else {
                    $clerkUserId = Db::name('order')->where(['activity_id' => $activityId, 'user_id' => $recomUserId])->where('clerk_user_id', '>', 0)->value('clerk_user_id');
                }
                // 生成预订单
                $orderId = Db::name('order')->insertGetId([
                    'activity_id' => $activityId,
                    'clerk_user_id' => empty($clerkUserId) ? 0 : $clerkUserId,
                    'recom_user_id' => empty($recomUserId) ? 0 : $recomUserId,
                    'user_id' => $user['id'],
                    'activity_title' => $data['activity_title'],
                    'order_sn' => date('YmdHis').strtoupper(randomkeys(5)).'A'.$activityId,
                    'order_status' => 0,
                    'create_time' => date('Y-m-d H:i:s'),
                ]);
                Db::name('activity_visitor')->where(['id' => $visitorId])->update(['order_id' => $orderId]);
                // 生成该活动下的用户角色
                if (!Db::name('activity_user_role')->where(['activity_id' => $activityId, 'user_id' => $user['id']])->find()) {
                    Db::name('activity_user_role')->insertGetId([
                        'activity_id' => $activityId,
                        'user_id' => $user['id'],
                        'role' => 0,
                        'create_time' => date('Y-m-d H:i:s'),
                    ]);
                }
            }
            // 增加操作日志
            Db::name('activity_operation_log')->insert([
                'activity_id' => $activityId,
                'user_id' => $user['id'],
                'type' => 2,
                'record' => '进入了该活动页面',
                'create_time' => date('Y-m-d H:i:s'),
            ]);
            // 获取数据
            $data['custom'] = Db::name('activity_custom')->where(['activity_id' => $activityId])->column('custom_value', 'custom_code');;
            $data['activity_visitor'] = Db::name('activity_visitor')
                ->alias('a')
                ->join('user b', 'a.user_id = b.id')
                ->where(['a.activity_id' => $activityId])
                ->field('b.nickname, b.avatar_url')
                ->order('a.id desc')->limit(200)->select()->toArray();
            foreach ($data['activity_visitor'] as &$value) {
                // 昵称打码
                if (!empty($value['nickname'])) {
                    $value['nickname'] = $this->maskNickname($value['nickname']);
                }
            }
            $data['box'] = Db::name('platform_box')->where(['id' => $data['platform_box_id']])->find();
            $data['box_prize'] = Db::name('platform_box_prize')->where(['platform_box_id' => $data['platform_box_id']])->select()->toArray();
            // 获取抽奖次数
            $visitor_user = Db::name('activity_visitor')->where(['activity_id' => $activityId, 'user_id' => $user['id']])->find();
            $data['activity_draw_num'] = $visitor_user['activity_draw_num'];
            $data['box_draw_num'] = $visitor_user['platform_box_draw_num'];
            // 获取订单信息
            $data['order'] = Db::name('order')->where(['activity_id' => $activityId, 'user_id' => $user['id']])->find();
            return $this->reSuccess('数据获取成功', $data);
        } else {
            return $this->reError('该活动不存在');
        }
    }

    /**
     * 对中文昵称进行打码处理
     * @param string $nickname 原始昵称
     * @return string 打码后的昵称
     */
    private function maskNickname($nickname)
    {
        $length = mb_strlen($nickname, 'UTF-8');
        // 如果昵称长度小于等于4个字符，则不进行打码
        if ($length <= 4) {
            return $nickname . '**';
        }
        // 获取前两个字符
        $prefix = mb_substr($nickname, 0, 2, 'UTF-8');
        // 获取最后两个字符
        $suffix = mb_substr($nickname, -2, 2, 'UTF-8');
        // 组合最终结果
        return $prefix . '**' . $suffix;
    }

    /**
     * 平台盲盒抽奖
     * @param Request $request
     * @return Response]
     */
    public function platformBoxPrizeDraw(Request $request) : Response
    {
        if (!request()->isPost()) {
            return $this->reError('请求方式错误');
        }

        $jwt = JwtToken::getExtend();
        $activityId = $request->post('activityId');
        $orderId = Db::name('order')->where(['activity_id' => $activityId, 'user_id' => $jwt['id']])->value('id');

        // 员工不能抽奖
        $activity = Db::name('activity')->where(['id' => $activityId])->find();
        $role = Db::name('activity_user_role')->where(['activity_id' => $activityId, 'user_id' => $jwt['id']])->value('role', 0);
        if ($activity['staff_is_platform_box'] == 0 && $role == 2) {
            return $this->reError('员工不能抽奖');
        }

        // 判断是否拥有抽奖资格
        $visitorInfo = Db::name('activity_visitor')->where(['activity_id' => $activityId, 'user_id' => $jwt['id']])->find();
        if (empty($visitorInfo)) {
            return $this->reError('无抽奖资格');
        }
        if ($visitorInfo['platform_box_draw_num'] > 0) {
            // 扣除抽奖次数
            Db::name('activity_visitor')->where(['id' => $visitorInfo['id']])->setDec('platform_box_draw_num');
            // 获取翻牌抽奖奖品
            $activity = Db::name('activity')->where(['id' => $activityId])->find();
            $prizeList = Db::name('platform_box_prize')->where(['platform_box_id' => $activity['platform_box_id']])->where('stock', '>', 0)->select()->toArray();
            // 计算累积概率数组
            $sortedPrizes = [];
            $totalProbability = 0;
            foreach ($prizeList as $value) {
                $totalProbability += ($value['odds'] / 100);
                $sortedPrizes[] = [
                    'id' => $value['id'],
                    'name' => $value['name'],
                    'image' => $value['image'],
                    'cumulative' => $totalProbability
                ];
            }
            // 生成随机数（范围：0 到 1）
            $randomNumber = mt_rand(0, 99999) / 100000;
            // 遍历累积概率数组，找到对应的奖品
            foreach ($sortedPrizes as $value) {
                if ($value['cumulative'] >= $randomNumber) {
                    unset($value['cumulative']);
                    $prize = $value;
                    break;
                }
            }

            if (empty($prizeInfo)) {
                $prize = Db::name('platform_box_prize')->where(['platform_box_id' => $activity['platform_box_id']])->where('stock', '>', 0)->order('odds desc')->find();
            }

            // 获取参与者信息
            $visitorInfo = Db::name('activity_visitor')->where(['activity_id' => $activityId, 'user_id' => $jwt['id']])->find();

            // 判断是否中奖
            if (!empty($prize)) {

                // 判断奖品库存是否充足
                $platformBoxPrize = Db::name('platform_box_prize')->where(['id' => $prize['id']])->find();
                if (empty($platformBoxPrize) || $platformBoxPrize['stock'] <= 0) {
                    return $this->reSuccess('数据获取成功', ['isPrize' => false, 'prizeName' => '很遗憾，没中奖', 'darwNum' => $visitorInfo['platform_box_draw_num']]);
                } else {
                    // 扣除库存
                    Db::name('platform_box_prize')->where(['id' => $prize['id']])->setDec('stock');
                }

                // 记录抽奖信息
                Db::name('payment_platform_box')->insert([
                    'activity_id' => $activityId,
                    'user_id' => $jwt['id'],
                    'prize_sn' => date('YmdHis').strtoupper(randomkeys(8)),
                    'order_id' => $orderId,
                    'platform_box_prize_id' => $prize['id'],
                    'prize_name' => $prize['name'],
                    'prize_image' => $prize['image'],
                    'status' => 0,
                    'create_time' => date('Y-m-d H:i:s')
                ]);

                // 查询奖品类型
                $prizeInfo = Db::name('platform_box_prize')->where(['id' => $prize['id']])->find();
                if ($prizeInfo['type'] == 2) {
                    try {
                        $disburse_sn = date('YmdHis').strtoupper(randomkeys(10));
                        (new \app\api\controller\OrderController)->batches($activityId, JwtToken::getExtend()['id'], $prizeInfo['name'], $disburse_sn, $prizeInfo['price'] * 100, '奖励');
                    } catch (\Exception $error) {
                        $error_remark = $error->response->message ?? $error->getMessage();
                    }
                    // 写入支出明细
                    Db::name('payment_disburse')->insert([
                        'activity_id' => $activity['id'],
                        'order_id' => $orderId,
                        'user_id' => JwtToken::getExtend()['id'],
                        'status' => empty($error_remark) ? 0 : 1,
                        'disburse_sn' => $disburse_sn,
                        'name' => $prizeInfo['name'],
                        'amount' => $prizeInfo['price'],
                        'remark' => empty($error_remark) ? '' : $error_remark,
                        'create_time' => date('Y-m-d H:i:s')
                    ]);
                }
                return $this->reSuccess('数据获取成功', ['isPrize' => true, 'prizeName' => $prize['name'], 'darwNum' => $visitorInfo['platform_box_draw_num']]);
            } else {
                return $this->reSuccess('数据获取成功', ['isPrize' => false, 'prizeName' => '很遗憾，没中奖', 'darwNum' => $visitorInfo['platform_box_draw_num']]);
            }

        } else {
            return $this->reError('抽奖次数不足');
        }
    }

    /**
     * 平台盲盒奖品详情
     * @return void
     */
    public function platformBoxPrizeInfo(Request $request) : Response
    {
        if (!request()->isGet()) {
            return $this->reError('请求方式错误');
        }

        $data = Db::name('platform_box_prize')->where(['id' => $request->get('id')])->field('image, price, name, detail_image')->find();
        return $this->reSuccess('数据获取成功', $data);
    }

    /**
     * 翻牌抽奖
     * @param Request $request
     * @return Response
     */
    public function prizeDraw(Request $request) : Response
    {
        if (!request()->isPost()) {
            return $this->reError('请求方式错误');
        }

        $jwt = JwtToken::getExtend();
        $activityId = $request->post('activityId');
        $activity = Db::name('activity')->where(['id' => $activityId])->find();

        // 员工不能抽奖
        $role = Db::name('activity_user_role')->where(['activity_id' => $activityId, 'user_id' => $jwt['id']])->value('role', 0);
        if ($activity['staff_is_draw'] == 0 && $role == 2) {
            return $this->reError('员工不能抽奖');
        }

        // 判断是否拥有抽奖资格
        $visitorInfo = Db::name('activity_visitor')->where(['activity_id' => $activityId, 'user_id' => $jwt['id']])->find();
        if (empty($visitorInfo)) {
            return $this->reError('无抽奖资格');
        }
        if ($visitorInfo['activity_draw_num'] > 0) {
            // 扣除抽奖次数
            Db::name('activity_visitor')->where(['id' => $visitorInfo['id']])->setDec('activity_draw_num');
            // 获取翻牌抽奖奖品
            $prizeList = Db::name('activity_prize')->where(['activity_id' => $activityId])->where('stock', '>', 0)->select()->toArray();
            // 计算累积概率数组
            $sortedPrizes = [];
            $totalProbability = 0;
            foreach ($prizeList as $value) {
                $totalProbability += ($value['odds'] / 100);
                $sortedPrizes[] = [
                    'id' => $value['id'],
                    'name' => $value['name'],
                    'image' => $value['image'],
                    'cumulative' => $totalProbability
                ];
            }
            // 生成随机数（范围：0 到 1）
            $randomNumber = mt_rand(0, 99999) / 100000;
            // 遍历累积概率数组，找到对应的奖品
            foreach ($sortedPrizes as $value) {
                if ($value['cumulative'] >= $randomNumber) {
                    unset($value['cumulative']);
                    $prizeInfo = $value;
                    break;
                }
            }

            if (empty($prizeInfo)) {
                $prizeInfo = Db::name('activity_prize')->where(['activity_id' => $activityId])->where('stock', '>', 0)->order('odds desc')->find();
            }

            // 获取参与者信息
            $visitorInfo = Db::name('activity_visitor')->where(['activity_id' => $activityId, 'user_id' => $jwt['id']])->find();

            // 判断是否中奖
            if (!empty($prizeInfo)) {

                // 判断奖品库存是否充足
                $activityPrize = Db::name('activity_prize')->where(['id' => $prizeInfo['id']])->find();
                if (empty($activityPrize) || $activityPrize['stock'] <= 0) {
                    return $this->reSuccess('数据获取成功', ['isPrize' => false, 'prizeName' => '很遗憾，没中奖', 'darwNum' => $visitorInfo['activity_draw_num']]);
                } else {
                    // 扣除库存
                    Db::name('activity_prize')->where(['id' => $prizeInfo['id']])->setDec('stock');
                }

                // 记录抽奖信息
                Db::name('payment_activity_prize')->insert([
                    'activity_id' => $activityId,
                    'user_id' => $jwt['id'],
                    'prize_sn' => date('YmdHis').strtoupper(randomkeys(8)),
                    'order_id' => Db::name('order')->where(['activity_id' => $activityId, 'user_id' => $jwt['id']])->value('id'),
                    'activity_prize_id' => $prizeInfo['id'],
                    'prize_name' => $prizeInfo['name'],
                    'prize_image' => $prizeInfo['image'],
                    'receive_status' => $activity['draw_prize_is_payment'] == 1 ? 0 : 1,
                    'status' => 0,
                    'create_time' => date('Y-m-d H:i:s')
                ]);
                return $this->reSuccess('数据获取成功', ['isPrize' => true, 'prizeName' => $prizeInfo['name'], 'darwNum' => $visitorInfo['activity_draw_num']]);
            } else {
                return $this->reSuccess('数据获取成功', ['isPrize' => false, 'prizeName' => '很遗憾，没中奖', 'darwNum' => $visitorInfo['activity_draw_num']]);
            }

        } else {
            return $this->reError('抽奖次数不足');
        }
    }

    /**
     * 提交翻牌抽奖中奖信息
     * @param Request $request
     * @return Response
     */
    public function submitDrawInfo(Request $request) : Response
    {
        if (!request()->isPost()) {
            return $this->reError('请求方式错误');
        }

        $jwt = JwtToken::getExtend();
        $activityId = $request->post('activityId');
        $data = $request->post('data');

        if (!empty($data['name'])) {
            $update['name'] = $data['name'];
        }
        if (!empty($data['phone'])) {
            $update['phone'] = $data['phone'];
        }
        if (!empty($data['customer_type'])) {
            $update['customer_type'] = $data['customer_type'];
        }
        if (!empty($update)) {
            Db::name('order')->where(['activity_id' => $activityId, 'user_id' => $jwt['id']])->update($update);
        }

        return $this->reSuccess('提交成功', $data);
    }

    /**
     * 增加分享量
     * @return void
     */
    public function addShareNum(Request $request) : Response
    {
        if (!request()->isPost()) {
            return $this->reError('请求方式错误');
        }

        $activityId = $request->post('activityId');
        $jwt = JwtToken::getExtend();
        $user = Db::name('user')->where(['id' => $jwt['id']])->find();

        // 增加操作日志
        Db::name('activity_operation_log')->insert([
            'activity_id' => $activityId,
            'user_id' => $user['id'],
            'type' => 3,
            'record' => '分享了该活动',
            'create_time' => date('Y-m-d H:i:s'),
        ]);

        Db::name('activity')->where(['id' => $activityId])->setInc('share_num');
        return $this->reSuccess('成功');
    }


    /**
     * 生成微信小程序二维码
     */
    public function wxappQrcode(Request $request) : Response
    {
        if (!request()->isGet()) {
            return $this->reError('请求方式错误');
        }

        // 生成小程序二维码
        $miniapp_appid = sysconfig('wechat','miniapp_appid');
        $miniapp_appsecret = sysconfig('wechat','miniapp_appsecret');

        $wxqrcode = (new \app\extend\WxUtil\WxTool)->wxappQrcode($miniapp_appid, $miniapp_appsecret, [
            'page' => $request->get('page', 'pages/index/index'),
            'scene' => $request->get('scene', ''),
            'width' => $request->get('width', '430')
        ]);
        if ($wxqrcode['code'] == 0) {
            // 发送图像
            return response(base64_decode($wxqrcode['data']))->header('Content-Type', 'image/png');
        } else {
            return $this->reError($wxqrcode['msg']);
        }
    }
}
